package com.unity.bh3.controller;

import com.unity.bh3.common.Result;
import com.unity.bh3.model.FriendMessage;
import com.unity.bh3.model.FriendRelationship;
import com.unity.bh3.model.UserStatus;
import com.unity.bh3.netty.WebSocketManager;
import com.unity.bh3.service.FriendService;
import com.unity.bh3.dto.UserInfoResponse;
import com.unity.bh3.dto.FriendRequestDTO;
import com.unity.bh3.dto.FriendMessageDTO;
import com.unity.bh3.dto.FriendListDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j
@RestController
@RequestMapping("/api/friend")
@Tag(name = "好友管理", description = "好友相关接口")
public class FriendController {

    @Autowired
    private FriendService friendService;

    @Autowired
    private WebSocketManager webSocketManager;

    @GetMapping("/search")
    @Operation(summary = "搜索用户", description = "根据昵称搜索用户")
    @Parameters({
            @Parameter(name = "User-Id", ref = "User-Id")
    })
    public Result<List<UserInfoResponse>> searchUsers(
            @RequestParam String nickname,
            @RequestParam(defaultValue = "5") int limit) {
        try {
            log.debug("搜索用户: nickname={}, limit={}", nickname, limit);
            List<UserInfoResponse> users = friendService.searchUsers(nickname, limit);
            return Result.success(users);
        } catch (Exception e) {
            log.error("搜索用户失败: ", e);
            throw e;
        }
    }

    @PostMapping("/request/{friendId}")
    @Operation(summary = "发送好友申请", description = "向指定用户发送好友申请")
    @Parameters({
            @Parameter(name = "User-Id", ref = "User-Id")
    })
    public Result<Void> sendFriendRequest(
            @RequestAttribute(required = true) Long userId,
            @PathVariable Long friendId) {
        try {
            log.debug("发送好友申请: userId={}, friendId={}", userId, friendId);
            if (userId.equals(friendId)) {
                webSocketManager.sendErrorMessage(userId, "不能添加自己为好友");
                throw new RuntimeException("不能添加自己为好友");
            }
            friendService.sendFriendRequest(userId, friendId);
            return Result.success();
        } catch (Exception e) {
            log.error("发送好友申请失败: ", e);
            throw e;
        }
    }

    @PostMapping("/request/{friendId}/handle")
    @Operation(summary = "处理好友申请", description = "接受或拒绝好友申请")
    @Parameters({
            @Parameter(name = "User-Id", ref = "User-Id")
    })
    public Result<Void> handleFriendRequest(
            @RequestAttribute(required = true) Long userId,
            @PathVariable Long friendId,
            @RequestParam boolean accept) {
        try {
            log.debug("处理好友申请: userId={}, friendId={}, accept={}", userId, friendId, accept);
            friendService.handleFriendRequest(userId, friendId, accept);
            return Result.success();
        } catch (Exception e) {
            log.error("处理好友申请失败: ", e);
            throw e;
        }
    }

    @GetMapping("/list")
    @Operation(summary = "获取好友列表", description = "获取用户的好友列表")
    @Parameters({
            @Parameter(name = "User-Id", ref = "User-Id")
    })
    public Result<List<FriendListDTO>> getFriendList(
            @RequestAttribute(required = true) Long userId) {
        try {
            log.debug("获取好友列表: userId={}", userId);
            List<FriendListDTO> friends = friendService.getFriendList(userId);
            return Result.success(friends);
        } catch (Exception e) {
            log.error("获取好友列表失败: ", e);
            throw e;
        }
    }

    @GetMapping("/requests")
    @Operation(summary = "获取好友申请列表", description = "获取收到的好友申请列表")
    @Parameters({
            @Parameter(name = "User-Id", ref = "User-Id")
    })
    public Result<List<FriendRequestDTO>> getFriendRequests(
            @RequestAttribute(required = true) Long userId) {
        try {
            log.info("开始获取好友申请列表: userId={}", userId);
            
            if (userId == null) {
                log.error("获取好友申请列表失败: userId为空");
                throw new RuntimeException("用户ID不能为空");
            }
            
            List<FriendRequestDTO> requests = friendService.getFriendRequests(userId);
            log.info("获取好友申请列表成功: userId={}, count={}", userId, requests.size());
            
            return Result.success(requests);
        } catch (RuntimeException e) {
            log.error("获取好友申请列表失败(业务异常): userId={}, error={}", userId, e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("获取好友申请列表失败(系统异常): userId={}", userId, e);
            throw new RuntimeException("获取好友申请列表失败，请稍后重试");
        }
    }

    // 获取与好友的历史消息
    @GetMapping("/history/{friendId}")
    @Operation(summary = "获取历史消息", description = "获取与指定好友的历史消息")
    @Parameters({
            @Parameter(name = "User-Id", ref = "User-Id")
    })
    public Result<List<FriendMessageDTO>> getHistoryMessages(
            @RequestAttribute(required = true) Long userId,
            @PathVariable Long friendId) {
        try {
            log.debug("获取历史消息: userId={}, friendId={}", userId, friendId);
            List<FriendMessageDTO> historyMessages = friendService.getHistoryMessages(userId, friendId);
            return Result.success(historyMessages);
        } catch (Exception e) {

            log.error("获取历史消息失败: ", e);
            throw e;
        }
    }

    @PostMapping("/message/{friendId}")
    @Operation(summary = "发送消息", description = "向指定好友发送消息")
    @Parameters({
            @Parameter(name = "User-Id", ref = "User-Id")
    })
    public Result<Void> sendMessage(
            @RequestAttribute(required = true) Long userId,
            @PathVariable Long friendId,
            @RequestBody String content) {
        try {
            log.debug("发送好友消息: userId={}, friendId={}, content={}", userId, friendId, content);
            friendService.sendMessage(userId, friendId, content);
            return Result.success();
        } catch (Exception e) {
            log.error("发送好友消息失败: ", e);
            throw e;
        }
    }

    @GetMapping("/messages/unread")
    public Result<List<FriendMessage>> getUnreadMessages(
            @RequestAttribute(required = true) Long userId) {
        try {
            log.debug("获取未读消息: userId={}", userId);
            List<FriendMessage> messages = friendService.getUnreadMessages(userId);
            return Result.success(messages);
        } catch (Exception e) {
            log.error("获取未读消息失败: ", e);
            throw e;
        }
    }

    @PostMapping("/message/{messageId}/read")
    public Result<Void> markMessageAsRead(@PathVariable Long messageId) {
        try {
            log.debug("标记消息已读: messageId={}", messageId);
            friendService.markMessageAsRead(messageId);
            return Result.success();
        } catch (Exception e) {
            log.error("标记消息已读失败: ", e);
            throw e;
        }
    }

    @PostMapping("/messages/{friendId}/read/all")
    public Result<Void> markAllMessagesAsRead(
            @RequestAttribute(required = true) Long userId,
            @PathVariable Long friendId) {
        try {
            log.debug("标记与好友的所有消息为已读: userId={}, friendId={}", userId, friendId);
            friendService.markAllMessagesAsRead(userId, friendId);
            return Result.success();
        } catch (Exception e) {
            log.error("标记与好友的所有消息为已读失败: ", e);
            throw e;
        }
    }

    @GetMapping("/status/{friendId}")
    public Result<UserStatus> getFriendStatus(@PathVariable Long friendId) {
        try {
            log.debug("获取好友状态: friendId={}", friendId);
            UserStatus status = friendService.getFriendStatus(friendId);
            return Result.success(status);
        } catch (Exception e) {
            log.error("获取好友状态失败: ", e);
            throw e;
        }
    }
    
    @DeleteMapping("/{friendId}")
    public Result<Void> deleteFriend(
            @RequestAttribute(required = true) Long userId,
            @PathVariable Long friendId) {
        try {
            log.info("删除好友: userId={}, friendId={}", userId, friendId);
            friendService.deleteFriend(userId, friendId);
            return Result.success();
        } catch (Exception e) {
            log.error("删除好友失败: ", e);
            throw e;
        }
    }
}